from math import floor, sqrt
from time import time
import numba
import numpy as np
from numba import cuda


def isprime(n):
    """
        :type n:int
        :rtype:List[int]
        """
    s=[True for i in range(n+1)]#首先默认所有的数都是质数
    z=[]#存放质数
    for i in range(2,n+1):#1不是质数
        if s[i]:#判断是否为质数，如果没有被标记就是质数
            z.append(i)
            for j in range(i+i,n+1,i):#剔除倍数（如果是质数，质数的倍数一定不是质数）
                s[j]=False
    return z

@cuda.jit
def IsPrime(num):
    if num == 2 or num == 3: return True

    if num % 6 != 1 and num % 6 != 5: return False

    for i in range(5, floor(sqrt(num)) + 1, 6):
        if num % i == 0 or num % (i + 2) == 0: return False
    return True

@cuda.jit
def add_one_atomic(x):
    cuda.atomic.add(x, 0, 1)  # Arguments are array, array index, value to add

@cuda.jit
def gpu_print(G,N):
    idx = cuda.threadIdx.x + cuda.blockIdx.x * cuda.blockDim.x
    if (2*idx+1 < N):
        if IsPrime(2*idx+1) == True and IsPrime(2*idx+1 + 2) == True:
            print(2*idx+1, 2*idx+1 + 2)
            cuda.atomic.add(G, 0, 1)


# array([160.])

if __name__ == '__main__':
    print("kaishi")
    start_time = time()
    dev_val = cuda.to_device(np.array([0]))
    print(dev_val)
    gpu_print[10**5, 1024](dev_val, 10**8)
    dev_val.copy_to_host()
    print(dev_val[0])
    print("all_time",time()-start_time)